#pragma once
#ifndef CLIB_EPOLL_H
#define CLIB_EPOLL_H

#include "clib_type.h"
#include "clib_queue.h"
#include "clib_spinlock.h"
#include "clib_ring.h"

#ifdef __cplusplus
extern "C" {
#endif

enum clib_epoll_ring_type {
	CLIB_EPOLL_EVENT_DEAL_WITH,
	CLIB_EPOLL_EVENT_SHOT_DOWN
};

enum clib_epoll_op
{
	CLIB_EPOLL_CTL_ADD = 1, 
	CLIB_EPOLL_CTL_DEL = 2, 
	CLIB_EPOLL_CTL_MOD = 3, 
};

enum clib_event_type
{
	CLIB_EPOLLNONE		= 0x000, 	/**< 无事件 */
	CLIB_EPOLLPRI		= 0x002,    /**< 可读事件 */
	CLIB_EPOLLIN		= 0x001,    /**< 优先事件 */
	CLIB_EPOLLOUT		= 0x004,    /**< 可写事件 */
	CLIB_EPOLLRDNORM	= 0x040,    /**< 正常读事件 */
	CLIB_EPOLLRDBAND	= 0x080,    /**< 带外读事件 */
	CLIB_EPOLLWRNORM	= 0x100,    /**< 正常写事件 */
	CLIB_EPOLLWRBAND	= 0x200,    /**< 带外写事件 */
	CLIB_EPOLLMSG		= 0x400,    /**< 消息事件 */
	CLIB_EPOLLERR		= 0x008,    /**< 错误事件 */
	CLIB_EPOLLHUP		= 0x010,    /**< 挂起事件 */
	CLIB_EPOLLRDHUP 	= 0x2000,   /**< 半关闭事件 */
	CLIB_EPOLLONESHOT	= (1 << 30),/**< 一次性事件 */ 
	CLIB_EPOLLET		= (1 << 31) /**< 边缘触发事件 */
};

typedef union clib_epoll_data
{
	void 	   *ptr;
	i32_t 		sfd;
	u32_t 		u32;
	u64_t 		u64;
} clib_epoll_data_t;

typedef struct clib_epoll_event
{
	u32_t 				events;
	clib_epoll_data_t 	data;
} clib_ep_event_t;

typedef struct clib_epoll_s
{
	clib_sock_t      *sock;				/**< socket **/
	clib_ring_t    	 *ev_ring;			/**< event事件列表 **/
	clib_ring_t      *sh_ring;
	i32_t             backlog;			/**< 每次获取的最大事件数量 **/
	clib_spinlock_t   lock;
	u64_t             event_post;		/**< 事件投递次数 **/
	u64_t             event_deal;		/**< 事件处理次数 **/
	u64_t     	   	  rego_n;
	clib_queue_t 	  event_list;
	clib_queue_t 	  rego_list;
} clib_epoll_t;

i32_t 
clib_epoll_create(i32_t size);

i32_t 
clib_epoll_ctl(i32_t efd, i32_t opt, i32_t sfd, clib_ep_event_t *event);

i32_t 
clib_epoll_wait(i32_t efd, clib_ep_event_t **events, i32_t max_events, int timeout);

i32_t
clib_epoll_update_event(clib_epoll_t* ep, clib_sock_t *sock, i32_t type, u32_t event);

#ifdef __cplusplus
}
#endif

#endif